<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>spring web annotations | haijd</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  <meta name="keywords" content="Spring Annotations" />
  
  
  
  
  <meta name="description" content="Spring MVC注解入门">
<meta name="keywords" content="Spring Annotations">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring Web Annotations">
<meta property="og:url" content="http://www.hais2.com/2018/06/13/Spring-Web-Annotations-1/index.html">
<meta property="og:site_name" content="haijd">
<meta property="og:description" content="Spring MVC注解入门">
<meta property="og:locale" content="default">
<meta property="og:image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1528780019766&di=68e5f2f2eef5b87bf5b5d54455fe994f&imgtype=jpg&src=http%3A%2F%2Fimg1.imgtn.bdimg.com%2Fit%2Fu%3D2161947716%2C2940818680%26fm%3D214%26gp%3D0.jpg">
<meta property="og:updated_time" content="2018-06-13T05:18:33.519Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Spring Web Annotations">
<meta name="twitter:description" content="Spring MVC注解入门">
<meta name="twitter:image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1528780019766&di=68e5f2f2eef5b87bf5b5d54455fe994f&imgtype=jpg&src=http%3A%2F%2Fimg1.imgtn.bdimg.com%2Fit%2Fu%3D2161947716%2C2940818680%26fm%3D214%26gp%3D0.jpg">
  
    <link rel="alternate" href="/atom.xml" title="haijd" type="application/atom+xml">
  
  <link rel="icon" href="/css/images/favicon.ico">
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link href="https://fonts.googleapis.com/css?family=Open+Sans|Montserrat:700" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic" rel="stylesheet" type="text/css">
  <link href="//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
  <style type="text/css">
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/9749f0/00000000000000000001008f/27/l?subset_id=2&fvd=n5) format("woff2");font-weight:500;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/90cf9f/000000000000000000010091/27/l?subset_id=2&fvd=n7) format("woff2");font-weight:500;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/8a5494/000000000000000000013365/27/l?subset_id=2&fvd=n4) format("woff2");font-weight:lighter;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/d337d8/000000000000000000010095/27/l?subset_id=2&fvd=i4) format("woff2");font-weight:400;font-style:italic;}</style>
    
  <link rel="stylesheet" id="athemes-headings-fonts-css" href="//fonts.googleapis.com/css?family=Yanone+Kaffeesatz%3A200%2C300%2C400%2C700&amp;ver=4.6.1" type="text/css" media="all">
  <link rel="stylesheet" href="/css/style.css">

  <script src="/js/jquery-3.1.1.min.js"></script>

  <!-- Bootstrap core CSS -->
  <link rel="stylesheet" href="/css/bootstrap.css" >
  <link rel="stylesheet" href="/css/hiero.css" >
  <link rel="stylesheet" href="/css/glyphs.css" >
  
    <link rel="stylesheet" href="/css/vdonate.css" >
  

</head>

<script>
var themeMenus = {};

  themeMenus["/"] = "Home"; 

  themeMenus["/archives"] = "Archives"; 

  themeMenus["/categories"] = "Categories"; 

  themeMenus["/tags"] = "Tags"; 

  themeMenus["/about"] = "About"; 

</script>


  <body data-spy="scroll" data-target="#toc" data-offset="50">


  <header id="allheader" class="site-header" role="banner">
  <div class="clearfix container">
      <div class="site-branding">

          <h1 class="site-title">
            
              <a href="/" title="haijd" rel="home"> haijd </a>
            
          </h1>

          
            <div class="site-description">Stay Hungry,Stay Foolish</div>
          
            
          <nav id="main-navigation" class="main-navigation" role="navigation">
            <a class="nav-open">Menu</a>
            <a class="nav-close">Close</a>
            <div class="clearfix sf-menu">

              <ul id="main-nav" class="nmenu sf-js-enabled">
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/">Home</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/archives">Archives</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/categories">Categories</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/tags">Tags</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/about">About</a> </li>
                    
              </ul>
            </div>
          </nav>


      </div>
  </div>
</header>




  <div id="container">
    <div id="wrap">
            
      <div id="content" class="outer">
        
          <section id="main" style="float:none;"><article id="post-Spring-Web-Annotations-1" style="width: 66%; float:left;" class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="clearfix post-1016 post type-post status-publish format-standard has-post-thumbnail hentry category-template-2 category-uncategorized tag-codex tag-edge-case tag-featured-image tag-image tag-template">
    
<div class="article-gallery">
  <div class="article-gallery-photos">
    
      <a class="article-gallery-img fancybox" href="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1528780019766&di=68e5f2f2eef5b87bf5b5d54455fe994f&imgtype=jpg&src=http%3A%2F%2Fimg1.imgtn.bdimg.com%2Fit%2Fu%3D2161947716%2C2940818680%26fm%3D214%26gp%3D0.jpg" rel="gallery_cjie4nakk006v3swacbxlmvw3">
        <img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1528780019766&di=68e5f2f2eef5b87bf5b5d54455fe994f&imgtype=jpg&src=http%3A%2F%2Fimg1.imgtn.bdimg.com%2Fit%2Fu%3D2161947716%2C2940818680%26fm%3D214%26gp%3D0.jpg" itemprop="image">
      </a>
    
  </div>
</div>

    
      <header class="article-header">
        
  
    <h1 class="thumb" class="article-title" itemprop="name">
      Spring Web Annotations
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	Posted on <a href="/2018/06/13/Spring-Web-Annotations-1/" class="article-date">
	  <time datetime="2018-06-13T02:09:46.000Z" itemprop="datePublished">June 13, 2018</time>
	</a>

      
	<span id="busuanzi_container_page_pv">
	  本文总阅读量<span id="busuanzi_value_page_pv"></span>次
	</span>

    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <blockquote>
<p>原文地址：<a href="http://www.baeldung.com/spring-mvc-annotations" target="_blank" rel="noopener">http://www.baeldung.com/spring-mvc-annotations</a><br>此篇为译文，由于英语水平有限，可能对原文的理解有误，欢迎指正，不甚感激！<br><!-- TOC --></p>
</blockquote>
<ul>
<li><a href="#1">1. 概览</a></li>
<li><a href="#2-requestmapping">2. <code>@RequestMapping</code></a></li>
<li><a href="#3-requestbody">3. <code>@RequestBody</code></a></li>
<li><a href="#4-pathvariable">4. <code>@PathVariable</code></a></li>
<li><a href="#5-requestparam">5. <code>@RequestParam</code></a></li>
<li><a href="#6">6. 响应相关的注解</a><ul>
<li><a href="#61-responsebody">6.1. <code>@ResponseBody</code></a></li>
<li><a href="#62-exceptionhandler">6.2. <code>@ExceptionHandler</code></a></li>
<li><a href="#63-responsestatus">6.3. <code>@ResponseStatus</code></a></li>
</ul>
</li>
<li><a href="#7-web">7. 其他Web相关注解</a><ul>
<li><a href="#71-restcontroller">7.1. <code>@RestController</code></a></li>
<li><a href="#72-modelattribute">7.2. <code>@ModelAttribute</code></a></li>
<li><a href="#73-crossorigin">7.3. <code>@CrossOrigin</code></a></li>
</ul>
</li>
<li><a href="#8">8. 总结</a></li>
</ul>
<!-- /TOC -->
<h1 id="1-概览"><a href="#1-概览" class="headerlink" title="1. 概览"></a>1. 概览</h1><p>在本篇教程中，我们将要探讨Spring web开发有关的注解(Spring MVC注解)，这些注解存在于<code>org.springframework.web.bind.annotation</code>包中。</p>
<h1 id="2-RequestMapping"><a href="#2-RequestMapping" class="headerlink" title="2. @RequestMapping"></a>2. <code>@RequestMapping</code></h1><p>简而言之，<code>@RequestMapping</code>标记<code>@Controller</code>类中的请求处理器(request handler)方法。可用的配置有：</p>
<ul>
<li><code>path</code>：或者别名<code>name</code>、<code>value</code>都可以作为参数名，它指定了哪个URL映射到当前的方法。</li>
<li><code>method</code>：协调处理HTTP请求的方法。</li>
<li><code>params</code>：根据HTTP请求参数的存在、不存在或者值来过滤请求。</li>
<li><code>headers</code>：根据HTTP请求的<code>headers</code>的存在、不存在或者值来过滤请求。</li>
<li><code>consumes</code>：限制哪些HTTP请求主体中的媒体类型可以被该方法使用。</li>
<li><code>produces</code>：限制改方法可以响应哪些HTTP媒体类型。   </li>
</ul>
<a id="more"></a>
<p>来看一个简单的例子：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">VehicleController</span> </span>&#123;</span><br><span class="line"> </span><br><span class="line">    <span class="meta">@RequestMapping</span>(value = <span class="string">"/vehicles/home"</span>, method = RequestMethod.GET)</span><br><span class="line">    <span class="function">String <span class="title">home</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"home"</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>如果我们在类级别上应用此注释，我们可以为<code>@Controller</code>类中的所有处理程序方法(request handler)提供默认设置。唯一的区别就是Spring在寻找URL映射的时候，不仅仅只看方法或者类上面的配置，而是会结合起来：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(value = <span class="string">"/vehicles"</span>, method = RequestMethod.GET)</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">VehicleController</span> </span>&#123;</span><br><span class="line"> </span><br><span class="line">    <span class="meta">@RequestMapping</span>(<span class="string">"/home"</span>)</span><br><span class="line">    <span class="function">String <span class="title">home</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"home"</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>此外，可以使用<code>@GetMapping</code>、<code>@PostMapping</code>、<code>@PutMapping</code>、<code>@DeleteMapping</code>以及<code>@PatchMapping</code>这些不同的<code>@RequestMapping</code>变种，可以单独的设置<code>GET</code>、<code>POST</code>、<code>PUT</code>、<code>DELETE</code>、<code>PATCH</code>请求。</p>
<p>这些是在Spring4.3版本以后可用的。</p>
<h1 id="3-RequestBody"><a href="#3-RequestBody" class="headerlink" title="3. @RequestBody"></a>3. <code>@RequestBody</code></h1><p>使用<code>@RequestBody</code>注解可以将HTTP请求body体映射到一个对象：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PostMapping</span>(<span class="string">"/save"</span>)</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">saveVehicle</span><span class="params">(@RequestBody Vehicle vehicle)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>反序列化是自动的，当然着取决于请求的content type的类型。</p>
<h1 id="4-PathVariable"><a href="#4-PathVariable" class="headerlink" title="4. @PathVariable"></a>4. <code>@PathVariable</code></h1><p>接下来，我们来谈谈<code>@PathVariable</code>。</p>
<p>此注解表示将方法参数绑定到URI模板变量。我们可以使用<code>@RequestMapping</code>注解指定URI模板变量，然后使用<code>@PathVariable</code>指定需要绑定的方法参数。</p>
<p>我们可以使用<code>name</code>或者别名绑定，有<code>value</code>参数的例子：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/&#123;id&#125;"</span>)</span><br><span class="line"><span class="function">Vehicle <span class="title">getVehicle</span><span class="params">(@PathVariable(<span class="string">"id"</span>)</span> <span class="keyword">long</span> id) </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>如果方法的参数名和URI模板变量的名称一致，那么我们就不需要在<code>@PathVariable</code>注解中指定了：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/&#123;id&#125;"</span>)</span><br><span class="line"><span class="function">Vehicle <span class="title">getVehicle</span><span class="params">(@PathVariable <span class="keyword">long</span> id)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>此外，我们还可以标记这个URI模板变量是不是必需的：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/&#123;id&#125;"</span>)</span><br><span class="line"><span class="function">Vehicle <span class="title">getVehicle</span><span class="params">(@PathVariable(required = <span class="keyword">false</span>)</span> <span class="keyword">long</span> id) </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h1 id="5-RequestParam"><a href="#5-RequestParam" class="headerlink" title="5. @RequestParam"></a>5. <code>@RequestParam</code></h1><p>我们可以使用<code>@RequestParam</code>注解访问HTTP请求参数：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping</span></span><br><span class="line"><span class="function">Vehicle <span class="title">getVehicleByParam</span><span class="params">(@RequestParam(<span class="string">"id"</span>)</span> <span class="keyword">long</span> id) </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p><code>@RequestParam</code>注解的配置选项和<code>PathVariable</code>注解一致。</p>
<p>除了一致的配置以外，当Spring从绑定的HTTP请求参数中获得了一个空值，或者根本没找到这个参数的时候，<code>@RequestParam</code>还可以为方法参数设置一个默认值，为了实现这一点，我们需要使用<code>defaultValue</code>这个参数：</p>
<p>提供默认的值的情况下，<code>required</code>参数会被设置为<code>false</code>(博主注：也就是无论如何都赋一个值)：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/buy"</span>)</span><br><span class="line"><span class="function">Car <span class="title">buyCar</span><span class="params">(@RequestParam(defaultValue = <span class="string">"5"</span>)</span> <span class="keyword">int</span> seatCount)</span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>除了访问HTTP请求的参数，像HTTP请求中的其他数据也可以访问到：<code>cookies</code>和<code>headers</code>，访问它们可以使用另外两个注解<code>@CookieValue</code>和<code>@RequestHeader</code>。可以像使用<code>@RequestParam</code>一样来配置这两个注解。</p>
<h1 id="6-响应相关的注解"><a href="#6-响应相关的注解" class="headerlink" title="6. 响应相关的注解"></a>6. 响应相关的注解</h1><h2 id="6-1-ResponseBody"><a href="#6-1-ResponseBody" class="headerlink" title="6.1. @ResponseBody"></a>6.1. <code>@ResponseBody</code></h2><p>如果我们对一个请求处理器(request handler)方法使用<code>@ResponseBody</code>注解，那么Spring会把这个方法的返回值当作响应本身(博主注：也就是不会当作视图名称返回，当作rest API使用可以返回json数据)：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ResponseBody</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/hello"</span>)</span><br><span class="line"><span class="function">String <span class="title">hello</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">"Hello World!"</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>如果我们在<code>@Controller</code>类上使用<code>@ResponseBody</code>注解，那么其内部所有的请求处理器(request handler)方法都会生效。</p>
<h2 id="6-2-ExceptionHandler"><a href="#6-2-ExceptionHandler" class="headerlink" title="6.2. @ExceptionHandler"></a>6.2. <code>@ExceptionHandler</code></h2><p>使用这个注解，我们可以声明一个自定义的错误处理器(error handler)方法。当请求处理器(request handler)方法抛出任何指定的异常时，Spring会调用此自定义方法。</p>
<p>被捕获的异常可以作为参数传递给方法：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ExceptionHandler</span>(IllegalArgumentException.class)</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">onIllegalArgumentException</span><span class="params">(IllegalArgumentException exception)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>博主注：上面的方法定义了一个处理<code>IllegalArgumentException</code>类型异常的方法，当任何的请求处理器(request handler)方法抛出这个异常，就会自动执行该方法。</p>
<h2 id="6-3-ResponseStatus"><a href="#6-3-ResponseStatus" class="headerlink" title="6.3. @ResponseStatus"></a>6.3. <code>@ResponseStatus</code></h2><p>如果我们使用<code>@ResponseStatus</code>注解标注一个请求处理器(request handler)方法，则可以自定义一个期望返回的HTTP状态码。我们可以使用<code>code</code>参数声明状态码，或者别名也可以。</p>
<p>另外，我们也可以使用<code>reason</code>参数提供一个“reason”。</p>
<p>可以在<code>@ExceptionHandler</code>方法上使用<code>@ResponseStatus</code>：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ExceptionHandler</span>(IllegalArgumentException.class)</span><br><span class="line"><span class="meta">@ResponseStatus</span>(value = HttpStatus.BAD_REQUEST,reason = <span class="string">"用户名和密码不匹配!"</span>)</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">onIllegalArgumentException</span><span class="params">(IllegalArgumentException exception)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>博主注：reason会在返回的响应体中出现。</p>
<h1 id="7-其他Web相关注解"><a href="#7-其他Web相关注解" class="headerlink" title="7. 其他Web相关注解"></a>7. 其他Web相关注解</h1><p>一些注解并不能直接的管理HTTP请求或者响应，在这一节中，我们将介绍这种最常见的注解。</p>
<h2 id="7-1-RestController"><a href="#7-1-RestController" class="headerlink" title="7.1. @RestController"></a>7.1. <code>@RestController</code></h2><p><code>@RestController</code>注解合并了<code>@Controller</code>和<code>@ResponseBody</code>这两个注解的功能。(博主注：也就是实现rest API的关键)</p>
<p>因此，下面这两组代码实现的功能是相同的：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="meta">@ResponseBody</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">VehicleRestController</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">VehicleRestController</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="7-2-ModelAttribute"><a href="#7-2-ModelAttribute" class="headerlink" title="7.2. @ModelAttribute"></a>7.2. <code>@ModelAttribute</code></h2><p>通过这个注解我们可以通过设置的数据模型(model)<code>key</code>访问已经在MVC控制器中的数据模型(model)：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PostMapping</span>(<span class="string">"/assemble"</span>)</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">assembleVehicle</span><span class="params">(@ModelAttribute(<span class="string">"vehicle"</span>)</span> Vehicle vehicleInModel) </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>类似<code>@PathVariable</code>和<code>@RequestParam</code>注解，我们如果方法参数名和数据模型(model)<code>key</code>一致，就可省略：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PostMapping</span>(<span class="string">"/assemble"</span>)</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">assembleVehicle</span><span class="params">(@ModelAttribute Vehicle vehicle)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>除了这些，<code>@ModelAttribute</code>还有另外一个地方会用到：如果我们在一个方法上标注，Spring会自动将方法的返回值添加到这个数据模型(model)中：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ModelAttribute</span>(<span class="string">"vehicle"</span>)</span><br><span class="line"><span class="function">Vehicle <span class="title">getVehicle</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>类似的，如果方法名和数据模型(model)<code>key</code>一致，那么也可以省略这个<code>key</code>：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ModelAttribute</span></span><br><span class="line"><span class="function">Vehicle <span class="title">vehicle</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>Spring在调用请求处理器(request handler)方法之前，他会先调用该类中所有的<code>@ModelAttribute</code>注解方法。</p>
<p>更多关于<code>@ModelAttribute</code>注解的信息，可以阅读<a href="http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation" target="_blank" rel="noopener">这篇文章</a>。</p>
<h2 id="7-3-CrossOrigin"><a href="#7-3-CrossOrigin" class="headerlink" title="7.3. @CrossOrigin"></a>7.3. <code>@CrossOrigin</code></h2><p><code>@CrossOrigin</code>注解可以在请求处理器(request handler)方法上启用允许跨域请求：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@CrossOrigin</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/hello"</span>)</span><br><span class="line"><span class="function">String <span class="title">hello</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">"Hello World!"</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>如果我们标记在一个类上，那么该类下面的所有请求处理器(request handler)方法都会允许跨域请求。</p>
<p>我们可以用这个注解的参数来微调CORS行为。</p>
<p>更多的信息，请查阅<a href="http://www.baeldung.com/spring-cors" target="_blank" rel="noopener">这篇文章</a>。</p>
<h1 id="8-总结"><a href="#8-总结" class="headerlink" title="8. 总结"></a>8. 总结</h1><p>在这片文章中，我们展现了怎么在Spring MVC中处理HTTP请求和响应，同样，文章中的示例代码可以在我们的<a href="https://github.com/eugenp/tutorials/tree/master/spring-mvc-java" target="_blank" rel="noopener">GitHub</a>上获得。</p>

      
    </div>
    <footer class="entry-meta entry-footer">
      
	<span class="ico-folder"></span>
    <a class="article-category-link" href="/categories/Java/">Java</a>

      
  <span class="ico-tags"></span>
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Spring-Annotations/">Spring Annotations</a></li></ul>

      
        <div id="donation_div"></div>

<script src="/js/vdonate.js"></script>
<script>
var a = new Donate({
  title: '如果觉得我的文章对您有用，请随意打赏。您的支持将鼓励我继续创作!', // 可选参数，打赏标题
  btnText: 'Donate', // 可选参数，打赏按钮文字
  el: document.getElementById('donation_div'),
  wechatImage: '/css/images/wechatPay.png',
  alipayImage: '/css/images/alipay.jpg'
});
</script>
      

      
        
	<section id="comments" class="comment">
	  <div id="disqus_thread">
	  <noscript>Please enable JavaScript to view the <a href="//disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
	  </div>
	</section>

	<script type="text/javascript">
	var disqus_shortname = 'haijdblog';
	(function(){
	  var dsq = document.createElement('script');
	  dsq.type = 'text/javascript';
	  dsq.async = true;
	  dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
	  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
	}());
	(function(){
	  var dsq = document.createElement('script');
	  dsq.type = 'text/javascript';
	  dsq.async = true;
	  dsq.src = '//' + disqus_shortname + '.disqus.com/count.js';
	  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
	}());
	</script>


      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2018/06/14/Vue-ElementUI-upload-file-controller/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          Vue-ElementUI upload组件的上传文件控制
        
      </div>
    </a>
  
  
    <a href="/2018/06/12/Spring-Core-Annotations-1/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">Spring Core Annotations</div>
    </a>
  
</nav>

  
</article>

<!-- Table of Contents -->

  <aside id="sidebar">
    <div id="toc" class="toc-article">
    <strong class="toc-title">Contents</strong>
    
      <ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#1-概览"><span class="nav-number">1.</span> <span class="nav-text">1. 概览</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#2-RequestMapping"><span class="nav-number">2.</span> <span class="nav-text">2. @RequestMapping</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#3-RequestBody"><span class="nav-number">3.</span> <span class="nav-text">3. @RequestBody</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#4-PathVariable"><span class="nav-number">4.</span> <span class="nav-text">4. @PathVariable</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#5-RequestParam"><span class="nav-number">5.</span> <span class="nav-text">5. @RequestParam</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#6-响应相关的注解"><span class="nav-number">6.</span> <span class="nav-text">6. 响应相关的注解</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#6-1-ResponseBody"><span class="nav-number">6.1.</span> <span class="nav-text">6.1. @ResponseBody</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-2-ExceptionHandler"><span class="nav-number">6.2.</span> <span class="nav-text">6.2. @ExceptionHandler</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-3-ResponseStatus"><span class="nav-number">6.3.</span> <span class="nav-text">6.3. @ResponseStatus</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#7-其他Web相关注解"><span class="nav-number">7.</span> <span class="nav-text">7. 其他Web相关注解</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#7-1-RestController"><span class="nav-number">7.1.</span> <span class="nav-text">7.1. @RestController</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-2-ModelAttribute"><span class="nav-number">7.2.</span> <span class="nav-text">7.2. @ModelAttribute</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-3-CrossOrigin"><span class="nav-number">7.3.</span> <span class="nav-text">7.3. @CrossOrigin</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#8-总结"><span class="nav-number">8.</span> <span class="nav-text">8. 总结</span></a></li></ol>
    
    </div>
  </aside>
</section>
        
      </div>
      <footer id="footer" class="site-footer">
  

  <div class="clearfix container">
      <div class="site-info">
	      &copy; 2018 haijd All Rights Reserved.
          
            <span id="busuanzi_container_site_uv">
              本站访客数<span id="busuanzi_value_site_uv"></span>人次  
              本站总访问量<span id="busuanzi_value_site_pv"></span>次
            </span>
          
      </div>
      <div class="site-credit">
        Theme by <a href="https://github.com/iTimeTraveler/hexo-theme-hiero" target="_blank">hiero</a>
      </div>
  </div>
</footer>


<!-- min height -->

<script>
    var contentdiv = document.getElementById("content");

    contentdiv.style.minHeight = document.body.offsetHeight - document.getElementById("allheader").offsetHeight - document.getElementById("footer").offsetHeight + "px";
</script>
    </div>
    <!-- <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
    <a href="/categories" class="mobile-nav-link">Categories</a>
  
    <a href="/tags" class="mobile-nav-link">Tags</a>
  
    <a href="/about" class="mobile-nav-link">About</a>
  
</nav> -->
    

<!-- mathjax config similar to math.stackexchange -->

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [ ['$','$'], ["\\(","\\)"] ],
      processEscapes: true
    }
  });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      tex2jax: {
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
    });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>

<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/scripts.js"></script>
<script src="/js/bootstrap.js"></script>
<script src="/js/main.js"></script>








	<script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
	</script>






  </div>

  <a id="rocket" href="#top" class=""></a>
  <script type="text/javascript" src="/js/totop.js" async=""></script>
</body>
</html>
